using System;
using System.Linq;
using System.Web.UI.WebControls;
using EPiServer.Web.PropertyControls;

namespace EPiBoost.Core.CustomProperties.EnumSelector
{
	/// <summary>
	/// PropertyControl implementation used for rendering PropertyEnumSelectorBase data.
	/// </summary>
	public class MultiEnumSelectorControl<T> : PropertyStringControl where T : struct
	{   
		System.Web.UI.WebControls.CheckBoxList _Checkboxes = new System.Web.UI.WebControls.CheckBoxList();
		
		/// <summary>
		/// Gets the PropertyEnumSelectorBase instance for this IPropertyControl.
		/// </summary>
		/// <value>The property that is to be displayed or edited.</value>
		public PropertyEnumSelectorBase<T> PropertyEnumSelectorBase
		{
			get
			{
				return PropertyData as PropertyEnumSelectorBase<T>;
			}
		}

		public override void CreateEditControls() 
		{
			if (true)
			{
				var options = EnumHelper.GetEnumCollectionFromEnum<T>(true);
				var selected = SelectedEnumCollection<T>.Parse((PropertyData.Value ?? string.Empty).ToString());
				foreach (var option in options)
				{
					var isSelected = selected.Any(x => x.Value.ToString() == option.Value.ToString());
					AddListItem(option, isSelected);
				}

				SetSelectedValue();

				this.ApplyControlAttributes(_Checkboxes);
				Controls.Add(_Checkboxes);
			}
		}

		public override void ApplyEditChanges()
		{
			if(_Checkboxes!=null)
			{
				string selected = _Checkboxes.Items.Cast<ListItem>().Where(item => item.Selected).Aggregate(string.Empty, (current, item) => current + (item.Value + ","));
				selected = selected.TrimEnd(',');

				this.PropertyData.Value = SelectedEnumCollection<T>.Parse(selected);
			}
		}
		
		private void AddListItem(SelectedEnum<T> option, bool isSelected)
		{
			var li = new ListItem(option.Value.ToString(), option.Value.ToString());
			li.Selected = isSelected;
			if (option.Attributes != null && !string.IsNullOrWhiteSpace(option.Attributes.DisplayName))
			{
				li.Text = option.Attributes.DisplayName;
			}
			if (option.Attributes != null && option.Attributes.Hidden)
			{
				li.Enabled = false; // hidden item
				li.Text += " (Hidden)";
			}
			else
			{
				_Checkboxes.Items.Add(li);
			}
		}

		private void SetSelectedValue()
		{
			if (this.PropertyData != null && this.PropertyData.Value != null)
			{
				string val = PropertyData.Value.ToString();
				var selected = _Checkboxes.Items.FindByValue(val);
				if (selected != null)
				{
					_Checkboxes.SelectedValue = val;
					selected.Enabled = true; // show hidden
				}
			}
		}
	}
}
